package com.easylinkin.linkappapi.grid.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.core.enums.EWhether;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.exceptions.ExceptionEnum;
import com.easylinkin.linkappapi.grid.entity.GridReportDay;
import com.easylinkin.linkappapi.grid.entity.GridReportDayDetail;
import com.easylinkin.linkappapi.grid.entity.GridReportDayUser;
import com.easylinkin.linkappapi.grid.mapper.GridReportDayUserMapper;
import com.easylinkin.linkappapi.grid.models.dto.GridReportDayUserSaveDTO;
import com.easylinkin.linkappapi.grid.models.vo.GridReportDayUserInfoVO;
import com.easylinkin.linkappapi.grid.service.IGridReportDayUserService;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import com.easylinkin.linkappapi.security.service.LinkappUserService;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 网格日报人员指定表 服务实现类
 *
 * @author kuyujie
 * @since 2024-05-16
 */
@Slf4j
@Setter(onMethod_ = @Resource)
@Service("gridReportDayUserService")
public class GridReportDayUserServiceImpl extends ServiceImpl<GridReportDayUserMapper, GridReportDayUser> implements IGridReportDayUserService {

    private LinkappUserService linkappUserService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveData(GridReportDay gridReportDay, List<GridReportDayUserSaveDTO> userList) {

        boolean hasDuplicates = userList.stream()
                .filter(e -> StrUtil.isNotBlank(e.getUserId()))
                .collect(Collectors.groupingBy(e -> e))
                .entrySet()
                .stream()
                .anyMatch(e -> e.getValue().size() > 1);

        if (hasDuplicates) {
            log.error("日报填报人重复");
            throw new BusinessException(ExceptionEnum.CommonExceptionEnum.DATA_CHECK_ERROR, "日报填报人重复");
        }

        LocalDateTime now = LocalDateTime.now();

        List<GridReportDayUser> entityList = new ArrayList<>(userList.size());

        for (int i = 0; i < userList.size(); i++) {
            GridReportDayUserSaveDTO user = userList.get(i);

            GridReportDayUser entity = GridReportDayUser.builder()
                    .reportId(gridReportDay.getId())
                    .gridId(user.getGridId())
                    .gridRoleName(user.getGridRoleName())
                    .userId(user.getUserId())
                    .sort(i)
                    .tenantId(gridReportDay.getTenantId())
                    .creatorId(gridReportDay.getCreatorId())
                    .creator(gridReportDay.getCreator())
                    .createTime(now)
                    .modifyId(gridReportDay.getModifyId())
                    .modifier(gridReportDay.getModifier())
                    .modifyTime(now)
                    .build();

            entityList.add(entity);
        }

        return this.saveBatch(entityList);
    }

    @Override
    public List<GridReportDayUserInfoVO> listByReportId(Long reportId, LocalDateTime submitDeadline) {
        List<GridReportDayUserInfoVO> userList = baseMapper.selectListByReportId(reportId);

        Set<String> userIdSet = userList.stream().map(GridReportDayUserInfoVO::getUserId).collect(Collectors.toSet());
        Map<String, LinkappUser> userMap = linkappUserService.mapUserByIds(userIdSet);

        LocalDateTime now = LocalDateTime.now();
        userList.parallelStream().forEach(item -> {
            if (ObjectUtil.isNull(item.getSubmitTime()) && now.isAfter(submitDeadline)) {
                item.setIsTimeout(EWhether.YES.getCode());
            } else {
                item.setIsTimeout(EWhether.NO.getCode());
            }

            LinkappUser linkappUser = userMap.get(item.getUserId());
            if (ObjectUtil.isNotNull(linkappUser)) {
                item.setNickname(linkappUser.getNickname());
            }
        });

        return userList;
    }

    @Override
    public GridReportDayUser getByReportIdUserId(Long reportId, String userId) {
        return baseMapper.selectOne(Wrappers.<GridReportDayUser>lambdaQuery()
                .eq(GridReportDayUser::getReportId, reportId)
                .eq(GridReportDayUser::getUserId, userId)
                .last("limit 1")
        );
    }

    @Override
    public boolean updateSubmit(GridReportDayDetail reportDayDetail) {
        GridReportDayUser entity = GridReportDayUser.builder()
                .id(reportDayDetail.getReportUserId())
                .submitTime(reportDayDetail.getModifyTime())
                .build();

        return this.updateById(entity);
    }
}